package live.sidian.database.synchronizer.sync.data.entity;

import cn.hutool.core.util.StrUtil;
import live.sidian.database.synchronizer.infrastructure.exception.SimpleSQLException;
import lombok.Getter;
import lombok.Setter;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Objects;

/**
 * 表的主键. 键为字段名, 值为字段
 *
 * @author sidian
 * @date 2021/4/15 19:15
 */
public class TablePriKey extends HashMap<String, Column> {
    /**
     * 所在表
     */
    @Setter
    @Getter
    String table;

    public TablePriKey(String table) {
        super();
        this.table = table;
    }

    public String toDeleteSql() {
        return String.format("delete from `%s` where %s", table, toWhereSql());
    }

    public String toSelectSql() {
        return String.format("select * from `%s` where %s", table, toWhereSql());
    }

    public String toWhereSql() {
        StringBuilder builder = new StringBuilder();
        for (String col : keySet()) {
            builder.append(String.format("`%s` = ? and", col));
        }
        String str = builder.toString();
        if (StrUtil.endWith(str, "and")) {
            str = str.substring(0, str.length() - "and".length());
        }
        return str;
    }

    public void setValue(PreparedStatement statement) {
        try {
            doSetValue(statement);
        } catch (SQLException e) {
            throw new SimpleSQLException(e);
        }
    }

    private void doSetValue(PreparedStatement statement) throws SQLException {
        int index = 0;
        for (String col : keySet()) {
            index++;
            Column column = get(col);
            if (column.value == null) {
                statement.setNull(index, column.type);
            } else {
                statement.setObject(index, column.value, column.type);
            }
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TablePriKey priKey = (TablePriKey) o;
        // 大小比较
        if (size() != priKey.size()) return false;
        // 列比较
        for (String key : keySet()) {
            if (!Objects.equals(get(key), priKey.get(key))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(values().toArray());
    }
}
